import crypto from 'crypto';
import { Logger } from '../utils/logger';

export interface QueryUserRequest {
  merchant_id: string;
  buyer_id: number;
  timestamp: number;
  sign: string;
}

export interface QueryUserResponse {
  code: number;
  message?: string;
  errMsg?: string;  // API实际返回的错误信息字段
  data?: {
    nickname: string;
  };
}

export interface SellCardRequest {
  merchant_id: string;
  buyer_id: number;
  product_id: number;
  timestamp: number;
  sign: string;
}

export interface SellCardResponse {
  code: number;
  message?: string;
  errMsg?: string;  // API实际返回的错误信息字段
  data?: any;
}


export class CardSellService {
  private readonly merchantId: string;
  private readonly secretKey: string;
  private readonly apiBaseUrl: string;

  constructor() {
    this.merchantId = process.env.TELEGRAM_MERCHANT_ID || 'DL79175852939219';
    this.secretKey = process.env.TELEGRAM_SECRET_KEY || 'H565J5n7MwJ715cb6bV03RMJ88LZ34D8';
    this.apiBaseUrl = 'https://i.partnerbosbos.com';

    if (!this.merchantId || !this.secretKey) {
      Logger.warn('商户售卡服务配置不完整', {
        hasMerchantId: !!this.merchantId,
        hasSecretKey: !!this.secretKey
      });
    }
  }

  /**
   * 检查售卡服务配置是否完整
   */
  isConfigured(): boolean {
    return !!(this.merchantId && this.secretKey);
  }

  /**
   * 生成签名
   * 规则：
   * 1. 在参数中加入 secret_key=xxx, 按照字典顺序排序 eg: k1=v1&k2=v2&secret_key=xxx
   * 2. 将上述字符串使用 md5 编码, 生成签名
   */
  private generateSignature(params: Record<string, any>): string {
    try {
      // 1. 复制参数并加入secret_key
      const signParams = { ...params };
      signParams.secret_key = this.secretKey;

      // 2. 获取所有键并按字典序排序（自然顺序）
      const keyList = Object.keys(signParams).sort();

      // 3. 拼接字符串 key=value, 用&拼接，排除sign字段
      const paramParts: string[] = [];
      for (const key of keyList) {
        if (key !== 'sign') { // 排除sign字段
          const value = String(signParams[key]); // 确保转为字符串
          paramParts.push(`${key}=${value}`);
        }
      }

      const paramStr = paramParts.join('&');

      // 4. MD5加密
      const signature = crypto.createHash('md5').update(paramStr).digest('hex');

      Logger.info('签名生成详情', {
        originalParams: params,
        signParamsWithSecret: { ...signParams, secret_key: '***' }, // 隐藏密钥
        sortedKeys: keyList,
        paramStr,
        generatedSignature: signature
      });

      return signature;
    } catch (error) {
      Logger.error('签名生成失败', error, { params });
      throw new Error(`签名生成失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 根据金币数量获取product_id（从数据库动态查询）
   */
  async getProductIdByCoins(coinAmount: number): Promise<number | null> {
    try {
      const { prisma } = await import('../db');

      const config = await prisma.productConfig.findFirst({
        where: {
          coinAmount: coinAmount,
          isActive: true
        }
      });

      return config?.productId || null;
    } catch (error) {
      Logger.error('Failed to query product config from database', error, { coinAmount });
      return null;
    }
  }

  /**
   * 根据充值金额计算金币数量和product_id
   */
  async calculateCoinsAndProductId(amount: number): Promise<{ coins: number; productId: number | null }> {
    // 按照5.5泰铢=1M金币的汇率计算
    const coins = Math.round((amount / 5.5) * 100) / 100; // 保留两位小数
    const productId = await this.getProductIdByCoins(coins);

    // 添加详细调试日志
    Logger.info('金币计算详情', {
      originalAmount: amount,
      calculatedCoins: coins,
      productId
    });

    return { coins, productId };
  }

  /**
   * 查询用户名
   */
  async queryUser(buyerId: number): Promise<QueryUserResponse> {
    if (!this.isConfigured()) {
      throw new Error('商户售卡服务未配置');
    }

    try {
      const timestamp = Date.now();
      const params = {
        merchant_id: this.merchantId,
        buyer_id: buyerId,
        timestamp
      };

      const sign = this.generateSignature(params);
      const requestData: QueryUserRequest = { ...params, sign };

      // 构建查询参数URL
      const queryParams = new URLSearchParams({
        merchant_id: requestData.merchant_id,
        buyer_id: requestData.buyer_id.toString(),
        timestamp: requestData.timestamp.toString(),
        sign: requestData.sign
      });

      const apiUrl = `${this.apiBaseUrl}/shop/query_user?${queryParams.toString()}`;

      Logger.info('查询用户名请求详情', {
        buyerId,
        merchantId: this.merchantId,
        timestamp,
        apiUrl,
        queryParams: queryParams.toString(),
        signatureParams: { ...params, secret_key: '***' },
        generatedSign: sign
      });

      let response: Response;
      let responseText: string;

      try {
        // 使用GET请求 + 查询参数
        Logger.info('发送GET请求查询用户', { apiUrl });

        response = await fetch(apiUrl, {
          method: 'GET',
          headers: {
            'Accept': 'application/json',
            'User-Agent': 'Mozilla/5.0 (compatible; CardSellService/1.0)'
          }
        });

        responseText = await response.text();
      } catch (error) {
        Logger.error('查询用户名网络请求失败', error, { buyerId, apiUrl });
        throw error;
      }

      // 完整打印响应信息
      Logger.info('查询用户名完整响应', {
        buyerId,
        responseStatus: response.status,
        responseStatusText: response.statusText,
        responseHeaders: Object.fromEntries(response.headers.entries()),
        responseTextLength: responseText.length,
        responseText: responseText, // 完整响应内容
        requestUrl: apiUrl
      });

      let result: QueryUserResponse;

      try {
        result = JSON.parse(responseText);
        Logger.info('查询用户名JSON解析成功', { buyerId, result });
      } catch (parseError) {
        Logger.error('查询用户名响应解析失败', parseError, {
          buyerId,
          responseStatus: response.status,
          responseText: responseText.substring(0, 1000)
        });

        // 如果不是JSON，可能是HTML错误页面或其他格式
        return {
          code: -1,
          message: `API响应格式错误: ${response.status} ${response.statusText}`,
          data: undefined
        };
      }

      if (response.ok && result.code === 0) {
        Logger.info('查询用户名成功', {
          buyerId,
          nickname: result.data?.nickname
        });
      } else {
        const errorMessage = result.message || result.errMsg || '未知错误';
        Logger.error('查询用户名失败', new Error(errorMessage), {
          buyerId,
          code: result.code,
          message: errorMessage
        });
      }

      return result;
    } catch (error) {
      Logger.error('查询用户名异常', error, { buyerId });
      throw new Error(`查询用户名失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 售卡
   */
  async sellCard(buyerId: number, productId: number): Promise<SellCardResponse> {
    if (!this.isConfigured()) {
      throw new Error('商户售卡服务未配置');
    }

    try {
      const timestamp = Date.now();
      const params = {
        merchant_id: this.merchantId,
        buyer_id: buyerId,
        product_id: productId,
        timestamp
      };

      const sign = this.generateSignature(params);
      const requestData: SellCardRequest = { ...params, sign };

      // 构建查询参数URL
      const queryParams = new URLSearchParams({
        merchant_id: requestData.merchant_id,
        buyer_id: requestData.buyer_id.toString(),
        product_id: requestData.product_id.toString(),
        timestamp: requestData.timestamp.toString(),
        sign: requestData.sign
      });

      const apiUrl = `${this.apiBaseUrl}/shop/sell_card?${queryParams.toString()}`;

      Logger.info('售卡请求详情', {
        buyerId,
        productId,
        merchantId: this.merchantId,
        timestamp,
        apiUrl,
        queryParams: queryParams.toString(),
        signatureParams: { ...params, secret_key: '***' },
        generatedSign: sign
      });

      let response: Response;
      let responseText: string;

      try {
        // 使用GET请求 + 查询参数
        Logger.info('发送GET请求售卡', { apiUrl });

        response = await fetch(apiUrl, {
          method: 'GET',
          headers: {
            'Accept': 'application/json',
            'User-Agent': 'Mozilla/5.0 (compatible; CardSellService/1.0)'
          }
        });

        responseText = await response.text();
      } catch (error) {
        Logger.error('售卡网络请求失败', error, { buyerId, productId, apiUrl });
        throw error;
      }

      // 完整打印响应信息
      Logger.info('售卡完整响应', {
        buyerId,
        productId,
        responseStatus: response.status,
        responseStatusText: response.statusText,
        responseHeaders: Object.fromEntries(response.headers.entries()),
        responseTextLength: responseText.length,
        responseText: responseText, // 完整响应内容
        requestUrl: apiUrl
      });

      let result: SellCardResponse;

      try {
        result = JSON.parse(responseText);
        Logger.info('售卡JSON解析成功', { buyerId, productId, result });
      } catch (parseError) {
        Logger.error('售卡响应解析失败', parseError, {
          buyerId,
          productId,
          responseStatus: response.status,
          responseText: responseText.substring(0, 1000)
        });

        // 如果不是JSON，可能是HTML错误页面或其他格式
        return {
          code: -1,
          message: `API响应格式错误: ${response.status} ${response.statusText}`,
          data: undefined
        };
      }

      if (response.ok && result.code === 0) {
        Logger.info('售卡成功', {
          buyerId,
          productId,
          merchantId: this.merchantId
        });
      } else {
        const errorMessage = result.message || result.errMsg || '未知错误';
        Logger.error('售卡失败', new Error(errorMessage), {
          buyerId,
          productId,
          code: result.code,
          message: errorMessage
        });
      }

      return result;
    } catch (error) {
      Logger.error('售卡异常', error, { buyerId, productId });
      throw new Error(`售卡失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 执行完整的售卡流程（查询用户+售卡）
   */
  async executeCardSell(buyerId: number, amount: number): Promise<{
    success: boolean;
    coins: number;
    productId: number | null;
    nickname?: string;
    errorMessage?: string;
    queryUserResult?: QueryUserResponse;
    sellCardResult?: SellCardResponse;
  }> {
    try {
      // 1. 计算金币数量和产品ID
      const { coins, productId } = await this.calculateCoinsAndProductId(amount);

      if (!productId) {
        return {
          success: false,
          coins,
          productId: null,
          errorMessage: `无法匹配金额${amount}THB对应的产品ID，计算得到${coins}M金币`
        };
      }

      // 2. 查询用户名
      const queryResult = await this.queryUser(buyerId);

      if (queryResult.code !== 0) {
        return {
          success: false,
          coins,
          productId,
          errorMessage: `查询用户失败: ${queryResult.message}`,
          queryUserResult: queryResult
        };
      }

      // 3. 执行售卡
      const sellResult = await this.sellCard(buyerId, productId);

      if (sellResult.code !== 0) {
        return {
          success: false,
          coins,
          productId,
          nickname: queryResult.data?.nickname,
          errorMessage: `售卡失败: ${sellResult.message}`,
          queryUserResult: queryResult,
          sellCardResult: sellResult
        };
      }

      // 4. 售卡成功
      return {
        success: true,
        coins,
        productId,
        nickname: queryResult.data?.nickname,
        queryUserResult: queryResult,
        sellCardResult: sellResult
      };

    } catch (error) {
      Logger.error('执行售卡流程异常', error, { buyerId, amount });
      return {
        success: false,
        coins: Math.round((amount / 5.5) * 100) / 100,
        productId: null,
        errorMessage: error instanceof Error ? error.message : '未知错误'
      };
    }
  }
}

// 创建单例实例
export const cardSellService = new CardSellService();

// 检查配置是否完整的工具函数
export function isCardSellConfigured(): boolean {
  return cardSellService.isConfigured();
}